// 除非遵守许可证，否则不得使用此文件。
// 您可以通过
// 
// www.apache.org/licenses/LICENSE-2.0 
// 
// 除非适用法律要求或书面同意，否则根据许可证分发的软件
// 按“原样”分发，
// 无任何明示或暗示的保证或条件。
// 请参阅许可证，了解管理许可的特定语言和
// 许可证下的限制。

package transport

import (
	"net"
	"time"
)

type ListenerOptions struct {
	Listener     net.Listener
	ListenConfig net.ListenConfig

	socketOpts       *SocketOpts
	tlsInfo          *TLSInfo
	skipTLSInfoCheck bool
	writeTimeout     time.Duration
	readTimeout      time.Duration
}

func newListenOpts(opts ...ListenerOption) *ListenerOptions {
	lnOpts := &ListenerOptions{}
	lnOpts.applyOpts(opts)
	return lnOpts
}

func (lo *ListenerOptions) applyOpts(opts []ListenerOption) {
	for _, opt := range opts {
		opt(lo)
	}
}

// IsTimeout如果侦听器定义了读/写超时，则返回true。
func (lo *ListenerOptions) IsTimeout() bool { return lo.readTimeout != 0 || lo.writeTimeout != 0 }

// IsSocketOpts如果侦听器选项包括套接字选项，则返回true。
func (lo *ListenerOptions) IsSocketOpts() bool {
	if lo.socketOpts == nil {
		return false
	}
	return lo.socketOpts.ReusePort || lo.socketOpts.ReuseAddress
}

// 如果listner选项包含TLSInfo，则IsTLS返回true。
func (lo *ListenerOptions) IsTLS() bool {
	if lo.tlsInfo == nil {
		return false
	}
	return !lo.tlsInfo.Empty()
}

// ListenerOption是可应用于侦听器的选项。
type ListenerOption func(*ListenerOptions)

// WithTimeout允许对侦听器应用读或写超时。
func WithTimeout(read, write time.Duration) ListenerOption {
	return func(lo *ListenerOptions) {
		lo.writeTimeout = write
		lo.readTimeout = read
	}
}

// WithSocketOpts定义将应用于侦听器的套接字选项。
func WithSocketOpts(s *SocketOpts) ListenerOption {
	return func(lo *ListenerOptions) { lo.socketOpts = s }
}

// WithTLSInfo向侦听器添加TLS凭据。
func WithTLSInfo(t *TLSInfo) ListenerOption {
	return func(lo *ListenerOptions) { lo.tlsInfo = t }
}

// WITHSKIPLSINFOCHECK当为真时，可以使用https方案创建传输
// 而不传递TLSInfo，避免出现未显示错误。跳过此检查
// 还需要TLSInfo未通过。
func WithSkipTLSInfoCheck(skip bool) ListenerOption {
	return func(lo *ListenerOptions) { lo.skipTLSInfoCheck = skip }
}
